package lg.minecraft.plugin.pokedex;

import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress;
import com.cobblemon.mod.common.api.pokedex.PokedexManager;
import com.cobblemon.mod.common.api.pokedex.SpeciesDexRecord;
import com.cobblemon.mod.common.pokemon.Species;
import lg.minecraft.plugin.cobblemoncore.util.BukkitNmsConverter;
import lg.minecraft.plugin.pokedex.storage.DataStorage;
import lg.minecraft.plugin.pokedex.storage.YMALStorage;
import net.minecraft.class_3222;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author langle__
 * @version 1.0
 */
public class PokedexPlayer {

    private final UUID uuid;
    private final PokedexManager pokedex;

    private boolean gen1 = false;
    private boolean gen2 = false;
    private boolean gen3 = false;
    private boolean gen4 = false;
    private boolean gen5 = false;
    private boolean gen6 = false;
    private boolean gen7 = false;
    private boolean gen8 = false;
    private boolean gen9 = false;
    private boolean all_gen = false;
    private List<String> receivedSpecies = new ArrayList<>();

    public PokedexPlayer(@NotNull Player player) {
        this.uuid = player.getUniqueId();
        class_3222 nmsPlayer = BukkitNmsConverter.toPlayer(player);
        this.pokedex = Cobblemon.INSTANCE.getPlayerDataManager().getPokedexData(nmsPlayer);
    }

    public boolean hasTrackedSpecies(@Nullable Species species) {
        if (species == null) return false;
        SpeciesDexRecord speciesRecord = pokedex.getSpeciesRecord(species.resourceIdentifier);
        if (speciesRecord == null) return false;
        PokedexEntryProgress knowledge = speciesRecord.getKnowledge();
        return knowledge == PokedexEntryProgress.CAUGHT;
    }

    public boolean hasClaimedSpeciesReward(@Nullable Species species) {
        if (species == null) return false;
        return receivedSpecies.contains(species.resourceIdentifier.toString());
    }

    public void markSpeciesRewardAsClaimed(@Nullable Species species) {
        if (species == null) return;
        DataStorage dataStorage = LGPokedex.getPokedexPlayerManger().getDataStorage();
        dataStorage.markSpeciesAsReceived(uuid, species);
        receivedSpecies.add(species.resourceIdentifier.toString());
    }

    public void unmarkSpeciesRewardAsClaimed(@Nullable Species species) {
        if (species == null) return;
        DataStorage dataStorage = LGPokedex.getPokedexPlayerManger().getDataStorage();
        dataStorage.unmarkSpeciesAsReceived(uuid, species);
        receivedSpecies.remove(species.resourceIdentifier.toString());
    }

    public void setGenerationRewardClaimed(@NotNull Generations generation, boolean claim) {
        DataStorage dataStorage = LGPokedex.getPokedexPlayerManger().getDataStorage();
        dataStorage.setGenerationRewardClaimed(uuid, generation, claim);
        switch (generation) {
            case GEN1 -> gen1 = claim;
            case GEN2 -> gen2 = claim;
            case GEN3 -> gen3 = claim;
            case GEN4 -> gen4 = claim;
            case GEN5 -> gen5 = claim;
            case GEN6 -> gen6 = claim;
            case GEN7 -> gen7 = claim;
            case GEN8 -> gen8 = claim;
            case GEN9 -> gen9 = claim;
            case ALL_GEN -> all_gen = claim;
        }
    }

    public boolean isGenerationRewardClaimed(Generations generation) {
        return switch (generation) {
            case GEN1 -> gen1;
            case GEN2 -> gen2;
            case GEN3 -> gen3;
            case GEN4 -> gen4;
            case GEN5 -> gen5;
            case GEN6 -> gen6;
            case GEN7 -> gen7;
            case GEN8 -> gen8;
            case GEN9 -> gen9;
            case ALL_GEN -> all_gen;
        };
    }

    public void loadData() {
        DataStorage dataStorage = LGPokedex.getPokedexPlayerManger().getDataStorage();
        gen1 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN1);
        gen2 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN2);
        gen3 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN3);
        gen4 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN4);
        gen5 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN5);
        gen6 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN6);
        gen7 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN7);
        gen8 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN8);
        gen9 = dataStorage.isGenerationRewardClaimed(uuid, Generations.GEN9);
        all_gen = dataStorage.isGenerationRewardClaimed(uuid, Generations.ALL_GEN);
        receivedSpecies = dataStorage.getClaimedRewardSpecies(uuid);
    }

    public void saveData() {
        DataStorage dataStorage = LGPokedex.getPokedexPlayerManger().getDataStorage();
        if (dataStorage instanceof YMALStorage yml) {
            yml.asyncSaveData(uuid);
        }
    }

    public UUID getUUID() {
        return uuid;
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) return true;
        if (object == null || getClass() != object.getClass()) return false;
        PokedexPlayer that = (PokedexPlayer) object;
        return Objects.equals(getUUID(), that.getUUID());
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(getUUID());
    }
}
